package com.adopapa.wechatapi.application.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import com.adopapa.wechatapi.domain.message.RequestMessage;
import com.adopapa.wechatapi.domain.message.RequestMessage.MessageType;
import com.adopapa.wechatapi.domain.message.ResponseMessage;
import com.adopapa.wechatapi.domain.message.TextResponseMessage;
import com.adopapa.wechatapi.enterprise.domain.event.EWechatEvent;
import com.adopapa.wechatapi.enterprise.domain.message.EImageRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.ELinkRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.ELocationRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.EShortVideoRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.ETextRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.EVideoRequestMessage;
import com.adopapa.wechatapi.enterprise.domain.message.EVoiceRequestMessage;
import com.adopapa.wechatapi.util.MessageUtil;
import com.adopapa.wechatapi.xstream.XstreamUtil;
import com.qq.weixin.mp.aes.WXBizMsgCrypt;

public class EWechatService {

	private final Logger logger = Logger.getLogger(EWechatService.class);

	/**
	 * 处理来自微信服务器的请求
	 */
	public void process(HttpServletRequest request, HttpServletResponse response, WXBizMsgCrypt crypt) throws Exception {
		// 微信加密签名
		String msgSignature = request.getParameter("msg_signature");
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");

		logger.info("msgSignature is ".concat(msgSignature).concat(" timestamp is ").concat(timestamp).concat(" nonce is ").concat(nonce));
		// 从请求中读取整个post数据
		InputStream inputStream = request.getInputStream();
		// commons.io.jar 方法
		String postData = IOUtils.toString(inputStream, "UTF-8");
		// Post打印结果
		logger.info(postData);

		String result = crypt.decryptMsg(msgSignature, timestamp, nonce, postData);
		Map<String, String> requestMap = MessageUtil.parseXml(result);
		logger.info(requestMap);

		// // 发送方帐号
		// String fromUserName = requestMap.get("FromUserName");
		// // 开发者微信号
		// String toUserName = requestMap.get("ToUserName");
		// 消息类型
		String msgType = requestMap.get("MsgType");

		RequestMessage requestMessage = null;
		if (MessageType.image.name().equalsIgnoreCase(msgType)) {
			requestMessage = new EImageRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.link.name().equalsIgnoreCase(msgType)) {
			requestMessage = new ELinkRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.location.name().equalsIgnoreCase(msgType)) {
			requestMessage = new ELocationRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.text.name().equalsIgnoreCase(msgType)) {
			requestMessage = new ETextRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.video.name().equalsIgnoreCase(msgType)) {
			requestMessage = new EVideoRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.shortvideo.name().equalsIgnoreCase(msgType)) {
			requestMessage = new EShortVideoRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.voice.name().equalsIgnoreCase(msgType)) {
			requestMessage = new EVoiceRequestMessage();
			requestMessage.fromMap(requestMap);
			processMessage(requestMessage, request, response, crypt);
		} else if (MessageType.event.name().equalsIgnoreCase(msgType)) {
			EWechatEvent weChatEvent = XstreamUtil.XML2Bean(result, EWechatEvent.class);
			processEvent(weChatEvent, request, response, crypt);
			logger.info(msgType);
		} else {
			logger.info(msgType);
			String agentType = requestMap.get("AgentType");
			if ("chat".equalsIgnoreCase(agentType)) {
				logger.info("from chat callback");
				PrintWriter out = response.getWriter();
				out.print(requestMap.get("PackageId"));
				out.close();
			} else if ("kf_internal".equalsIgnoreCase(agentType)) {
				//processCustomerServiceMessage();
				logger.info("kf_internal");
				TextResponseMessage responseMessage = new TextResponseMessage();
				responseMessage.setCreateTime(Calendar.getInstance().getTime().getTime());
				responseMessage.setFromUserName("wx406ea2215654009e");
				responseMessage.setToUserName("F001");
				responseMessage.setContent("您的反馈已经记录, 谢谢您的支持!");
				sendResponseMessage(responseMessage, request, response, crypt);
				logger.info(responseMessage.toXml());
			} else if ("kf_external".equalsIgnoreCase(agentType)) {
				
			}
		}

	}

	/**
	 * 处理接受事件推送
	 */
	public void processEvent(EWechatEvent weChatEvent, HttpServletRequest request, HttpServletResponse response, WXBizMsgCrypt crypt) throws Exception {
	}

	/**
	 * 处理接受消息
	 */
	public void processMessage(RequestMessage requestMessage, HttpServletRequest request, HttpServletResponse response, WXBizMsgCrypt crypt) throws Exception {
		TextResponseMessage responseMessage = new TextResponseMessage();
		responseMessage.setCreateTime(Calendar.getInstance().getTime().getTime());
		responseMessage.setFromUserName(requestMessage.getToUserName());
		responseMessage.setToUserName(requestMessage.getFromUserName());
		responseMessage.setContent("您的反馈已经记录, 谢谢您的支持!");
		sendResponseMessage(responseMessage, request, response, crypt);
	}
	
	

	/**
	 * 被动回复消息
	 * 
	 * @throws IOException
	 * @throws Exception
	 */
	public static void sendResponseMessage(ResponseMessage responseMessage, HttpServletRequest request, HttpServletResponse response, WXBizMsgCrypt crypt) throws Exception {
		PrintWriter out = response.getWriter();
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");
		String result = crypt.encryptMsg(responseMessage.toXml(), timestamp, nonce);
		out.print(result);
		out.close();
	}

}
